<?
abstract class ReflectionUtils{
    private static function getSimpleValue($obj, $key){
        $getKey = 'get'.$key;
        return $obj->$getKey();
    }

    private static function setSimpleValue($obj, $key, $value){
        $setKey = 'set'.$key;
        return $obj->$setKey($value);
    }

    /**
     * Gets value over Reflection get
     */
    public static function getFieldValue($obj, $key){
        $keys = explode('.', $key);
        if(count($keys) == 1){
            return ReflectionUtils::getSimpleValue($obj, $key);
        }

        $value = ReflectionUtils::getSimpleValue($obj, $keys[0]);
        $keyCount = 1;

        do {
            $value = ReflectionUtils::getSimpleValue($value, $keys[$keyCount]);
        }while($keyCount++ < count($keys) - 1);

        return $value;
    }

    /**
     * Gets value accessing directly to the variable
     */
    public static function getValue($obj, $key){
        $keys = explode('.', $key);
        if(count($keys) == 1){
            return $obj->$key;
        }

        $value = ReflectionUtils::getSimpleValue($obj, $keys[0]);
        $keyCount = 0;

        while($keyCount++ < count($keys) - 2){
            $value = ReflectionUtils::getSimpleValue($value, $keys[$keyCount]);
        }

        $keey = $keys[count($keys)-1];
        return $value->$keey;
    }

    /**
     * Puts value on the object over setter
     */
    public static function setFieldValue($obj, $key, $val){
        $keys = explode('.', $key);
        if(count($keys) == 1){
            return ReflectionUtils::setSimpleValue($obj, $key, $val);
        }

        $value = ReflectionUtils::getSimpleValue($obj, $keys[0]);
        $keyCount = 0;

        while($keyCount++ < count($keys) - 2){
            $value = ReflectionUtils::getSimpleValue($value, $keys[$keyCount]);
        }

        ReflectionUtils::setSimpleValue($value, $keys[count($keys)-1], $val);
    }

    /**
     * Puts value not over setter, but accessing directly to the object
     */
    public static function setValue($obj, $key, $val){
        $keys = explode('.', $key);
        if(count($keys) == 1){
            $obj->$key = $val;
        }

        $value = ReflectionUtils::getSimpleValue($obj, $keys[0]);
        $keyCount = 0;

        while($keyCount++ < count($keys) - 2){
            $value = ReflectionUtils::getSimpleValue($value, $keys[$keyCount]);
        }

        $keey = $keys[count($keys)-1];
        $value->$keey = $val;
    }

    public static function getSubClasses($parentClassName){
        $classes = array();
        foreach (get_declared_classes() as $className)
        {
            if (is_subclass_of($className, $parentClassName))
                $classes[] = $className;
        }

        return $classes;

    }
}

?>